home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / c68_445b.zoo / src / out68k_jas.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-31  |  12.5 KB  |  718 lines

  1. /*
  2.  * C compiler
  3.  * ==========
  4.  *
  5.  * Copyright 1989, 1990, 1991 Christoph van Wuellen.
  6.  * Credits to Matthew Brandt.
  7.  * All commercial rights reserved.
  8.  *
  9.  * This compiler may be redistributed as long there is no
  10.  * commercial interest. The compiler must not be redistributed
  11.  * without its full sources. This notice must stay intact.
  12.  *
  13.  * History:
  14.  *
  15.  * 1989   starting an 68000 C compiler, starting with material
  16.  *        originally by M. Brandt
  17.  * 1990   68000 C compiler further bug fixes
  18.  *        started i386 port (December)
  19.  * 1991   i386 port finished (January)
  20.  *        further corrections in the front end and in the 68000
  21.  *        code generator.
  22.  *        The next port will be a SPARC port
  23.  */
  24.  
  25. #include "config.h"
  26.  
  27. #define    MAX_WIDTH    60
  28.  
  29. #ifdef MC680X0
  30. #ifdef TARGET_JAS
  31.  
  32. #include    "chdr.h"
  33. #include    "expr.h"
  34. #include    "gen.h"
  35. #include    "cglbdec.h"
  36.  
  37. #ifdef MULTIPLE_ASSEMBLERS
  38. #define PRIVATE    static
  39. #undef    put_code
  40. #undef    put_string
  41. #undef    put_label
  42. #undef    put_byte
  43. #undef    put_char
  44. #undef    put_word
  45. #undef    put_long
  46. #undef    put_pointer
  47. #undef    put_short
  48. #undef    put_storage
  49. #undef    dumplits
  50. #undef    put_external
  51. #undef    put_global
  52. #undef    put_align
  53. #undef    nl
  54. #undef    cseg
  55. #undef    dseg
  56. #undef    put_float
  57. #undef    put_double
  58. #undef    put_longdouble
  59. #else
  60. #define    PRIVATE
  61. #endif /* MULTIPLE_ASSEMBLERS */
  62.  
  63. enum e_gt {
  64.     bytegen, wordgen, longgen, floatgen, nogen
  65. };
  66. enum e_sg {
  67.     noseg, codeseg, dataseg, bssseg
  68. };
  69.  
  70. #if defined(__STDC__) || defined(__cplusplus)
  71. #define P_(s) s
  72. #else
  73. #define P_(s) ()
  74. #endif
  75.  
  76. /* out68k_jas.c */
  77. static void putop P_((OPCODE));
  78. static void putconst P_((EXPR *));
  79. static void putlen P_((int));
  80. static void putamode P_((ADDRESS *));
  81. static void put_mask P_((REGMASK));
  82. static void put_rmask P_((REGMASK));
  83. static void put_smask P_((REGMASK));
  84. static void putreg P_((int));
  85. static void put_header P_((enum e_gt, SIZE));
  86. static void seg P_((enum e_sg, char *));
  87. static void bseg P_((void));
  88. PRIVATE void put_string P_((char *));
  89. PRIVATE void put_align P_((SIZE));
  90. PRIVATE void put_long P_((long));
  91. PRIVATE void nl P_((void));
  92. PRIVATE void cseg P_((void));
  93. PRIVATE void dseg P_((void));
  94. PRIVATE void put_label P_((LABEL));
  95. PRIVATE void put_external P_((char *));
  96. PRIVATE void put_byte P_((int));
  97. PRIVATE void put_char P_((int));
  98.  
  99. #undef P_
  100.  
  101. /* variable initialization */
  102.  
  103. static enum e_gt gentype = nogen;
  104. static enum e_sg curseg = noseg;
  105. static int       outcol = 0;
  106. static SIZE     align_type;
  107.  
  108. #define    prefix    "L"
  109. #define comment    ";"
  110.  
  111. static char *opl[] = {
  112.     "move",        /* op_move */
  113.     "moveq",    /* op_moveq */
  114.     "add",        /* op_add */
  115.     "add",        /* op_addi */
  116.     "addq",        /* op_addq */
  117.     "sub",        /* op_sub */
  118.     "sub",        /* op_subi */
  119.     "subq",        /* op_subq */
  120.     "muls",        /* op_muls */
  121.     "mulu",        /* op_mulu */
  122.     "divs",        /* op_divs */
  123.     "divu",        /* op_divu */
  124.     "and",        /* op_and */
  125.     "and",        /* op_andi */
  126.     "or",        /* op_or */
  127.     "or",        /* op_ori */
  128.     "eor",        /* op_eor */
  129.     "asl",        /* op_asl */
  130.     "lsr",        /* op_lsr */
  131.     "jmp",        /* op_jmp */
  132.     "jsr",        /* op_jsr */
  133.     "movem",    /* op_movem */
  134.     "rts",        /* op_rts */
  135.     "bra",        /* op_bra */
  136.     "beq",         /* op_beq */
  137.     "bne",        /* op_bne */
  138.     "blt",        /* op_blt */
  139.     "ble",        /* op_ble */
  140.     "bgt",        /* op_bgt */
  141.     "bge",        /* op_bge */
  142.     "bhi",         /* op_bhi */
  143.     "bcc",         /* op_bhs */
  144.     "bcs",         /* op_blo */
  145.     "bls",         /* op_bls */
  146.     "btst",        /* op_btst */
  147.     "tst",        /* op_tst */
  148.     "ext",        /* op_ext */
  149.     "lea",        /* op_lea */
  150.     "swap",        /* op_swap */
  151.     "neg",        /* op_neg */
  152.     "not",        /* op_not */
  153.     "cmp",        /* op_cmp */
  154.     "clr",        /* op_clr */
  155.     "link",        /* op_link */
  156.     "unlk",        /* op_unlk */
  157.     "pea",        /* op_pea */
  158.     "cmp",        /* op_cmpi */
  159.     "dbra",        /* op_dbra */
  160.     "asr",        /* op_asr */
  161.     "rol",        /* op_rol */
  162.     "ror",        /* op_ror */
  163.     "seq",         /* op_seq */
  164.     "sne",        /* op_sne */
  165.     "slt",        /* op_slt */
  166.     "sle",        /* op_sle */
  167.     "sgt",        /* op_sgt */
  168.     "sge",        /* op_sge */
  169.     "shi",         /* op_shi */
  170.     "scc",         /* op_shs */
  171.     "scs",         /* op_slo */
  172.     "sls",         /* op_sls */
  173.     "st",        /* op_st */
  174. #ifdef TRAP_GEN
  175.     "trap",        /* op_trap */
  176. #endif /* TRAP_GEN */
  177.     comment"line",    /* op_line */
  178.     0,        /* op_label */
  179. };
  180.  
  181. static void
  182. putop(op)
  183.     OPCODE       op;
  184. {
  185.   if (op >= OP_MIN && op <= OP_MAX && opl[op] != (char *)0)
  186.     oprintf ("\t%s",opl[op]);
  187.   else
  188.     fatal(__FILE__,"putop","illegal opcode %d",op);
  189. }
  190.  
  191. static void
  192. putconst(offset)
  193. /*
  194.  * put a constant to the output file.
  195.  */
  196.     EXPR   *offset;
  197. {
  198.  
  199.     switch (offset->nodetype) {
  200.       case en_autocon:
  201.       case en_icon:
  202.     oprintf("%ld", offset->v.i);
  203.     break;
  204. #ifndef FLOAT_BOOTSTRAP
  205. #ifdef FLOAT_MFFP
  206.       case en_fcon:
  207.     oprintf("$%lx", genffp(offset->v.f));
  208.     break;
  209. #endif /* FLOAT_MFFP */
  210. #endif /* FLOAT_BOOTSTRAP */
  211.       case en_labcon:
  212.     oprintf(prefix"%u", (unsigned)offset->v.l);
  213.     break;
  214.       case en_nacon:
  215.         oprintf("%s",outlate(offset->v.sp));
  216.     break;
  217.       case en_add:
  218.     putconst(offset->v.p[0]);
  219.     oprintf("+");
  220.     putconst(offset->v.p[1]);
  221.     break;
  222.       case en_sub:
  223.     putconst(offset->v.p[0]);
  224.     oprintf("-");
  225.     putconst(offset->v.p[1]);
  226.     break;
  227.       case en_uminus:
  228.     oprintf("-");
  229.     putconst(offset->v.p[0]);
  230.     break;
  231.       default:
  232.     fatal(__FILE__,"putconst","illegal constant node %d",offset->nodetype);
  233.     break;
  234.     }
  235. }
  236.  
  237. static void
  238. putlen(l)
  239. /*
  240.  * append the length field to an instruction.
  241.  */
  242.     int             l;
  243. {
  244.     if (l == 0)
  245.     return;
  246.     oprintf(".");
  247.     switch (l) {
  248.       case 1:
  249.     oprintf("b");
  250.     break;
  251.       case 2:
  252.     oprintf("w");
  253.     break;
  254.       case 4:
  255.     oprintf("l");
  256.     break;
  257.       default:
  258.     fatal(__FILE__,"putlen","illegal length field %d",l);
  259.     break;
  260.     }
  261. }
  262.  
  263. static void
  264. putamode(ap)
  265. /*
  266.  * output a general addressing mode.
  267.  */
  268.     ADDRESS   *ap;
  269. {
  270.     switch (ap->mode) {
  271.       case am_immed:
  272.     oprintf("#");
  273.     /*FALLTHRU*/
  274.       case am_direct:
  275.     putconst(ap->offset);
  276.     break;
  277.       case am_areg:
  278.     oprintf("a%d", ap->preg);
  279.     break;
  280.       case am_dreg:
  281.     oprintf("d%d", ap->preg);
  282.     break;
  283.       case am_ind:
  284.     oprintf("(a%d)", ap->preg);
  285.     break;
  286.       case am_ainc:
  287.     oprintf("(a%d)+", ap->preg);
  288.     break;
  289.       case am_adec:
  290.     oprintf("-(a%d)", ap->preg);
  291.     break;
  292.       case am_indx:
  293.     putconst(ap->offset);
  294.     oprintf("(a%d)", ap->preg);
  295.     break;
  296.       case am_indx2:
  297.     putconst(ap->offset);
  298.     oprintf("(a%d,d%d.l)", ap->preg, ap->sreg);
  299.     break;
  300.       case am_indx3:
  301.     putconst(ap->offset);
  302.     oprintf("(a%d,a%d.l)", ap->preg, ap->sreg);
  303.     break;
  304. #ifdef JAS_PATCH
  305.       case am_indx4:
  306.     putconst(ap->offset);
  307.     oprintf("(a%d,d%d.w)", ap->preg, ap->sreg);
  308.     break;
  309. #endif /* JAS_PATCH */
  310.       case am_rmask:
  311.     put_rmask((REGMASK) ap->offset->v.i);
  312.     break;
  313.       case am_smask:
  314.     put_smask((REGMASK) ap->offset->v.i);
  315.     break;
  316.       case am_line:
  317.     putconst(ap->offset);
  318.     break;
  319.       default:
  320.     fatal(__FILE__,"putamode","illegal address mode %d",ap->mode);
  321.     break;
  322.     }
  323. }
  324.  
  325. PRIVATE void
  326. put_code(op, len, aps, apd)
  327. /*
  328.  * output a generic instruction.
  329.  */
  330.     ADDRESS   *aps, *apd;
  331.     int             len;
  332.     OPCODE       op;
  333. {
  334.     putop(op);
  335.     putlen(len);
  336.     if (aps != 0) {
  337.     oprintf("\t");
  338.     putamode(aps);
  339.     if (apd != 0) {
  340.         oprintf(",");
  341.         putamode(apd);
  342.     }
  343.     }
  344.     oprintf("\n");
  345. }
  346.  
  347. static void
  348. put_mask(mask)
  349. /*
  350.  * generate a register mask.
  351.  */
  352.     REGMASK     mask;
  353. {
  354.     int         i;
  355.     BOOL     pending = 0;
  356.     if (mask & 1) {
  357.     putreg(0);
  358.     pending = 1;
  359.     }
  360.     for (i = 1; i <= 15; i++)
  361.     if ((mask = mask >> 1) & 1) {
  362.         if (pending)
  363.         oprintf("/");
  364.         putreg(i);
  365.         pending = 1;
  366.     }
  367. }
  368.  
  369. static void
  370. put_smask(mask)
  371. /*
  372.  * generate a register mask for save.
  373.  */
  374.     REGMASK     mask;
  375. {
  376.     put_mask(mask);
  377. }
  378.  
  379. static void
  380. put_rmask(mask)
  381. /*
  382.  * generate a register mask for restore.
  383.  */
  384.     REGMASK     mask;
  385. {
  386.     put_mask(mask);
  387. }
  388.  
  389. static void
  390. putreg(r)
  391. /*
  392.  * generate a register name from a tempref number.
  393.  */
  394.     int             r;
  395. {
  396.     if (r < 8)
  397.     oprintf("d%d", r);
  398.     else
  399.     oprintf("a%d", r - 8);
  400. }
  401.  
  402. PRIVATE void
  403. put_string(s)
  404. /*
  405.  * generate a named label.
  406.  */
  407.     char           *s;
  408. {
  409.     oprintf("%s:\n",outlate(s));
  410. }
  411.  
  412. PRIVATE void
  413. put_label(lab)
  414. /*
  415.  * output a compiler generated label.
  416.  */
  417.     LABEL     lab;
  418. {
  419.     oprintf(prefix"%u:\n", (unsigned int)lab);
  420. }
  421.  
  422.  
  423. static void
  424. put_header (gtype, al)
  425.     enum e_gt gtype;
  426.     SIZE al;
  427. {
  428.     static char *directive[] = {
  429.     "dc.b\t",    /* bytegen */
  430.     "dc.w\t",    /* wordgen */
  431.     "dc.l\t",    /* longgen */
  432.     };
  433.  
  434.     if (gentype != gtype || outcol >= MAX_WIDTH) {
  435.     put_align(al);
  436.     gentype = gtype;
  437.     outcol = 15;
  438.     oprintf("\t%s", directive[gtype]);
  439.     } else
  440.     oprintf(",");
  441. }
  442.  
  443. PRIVATE void
  444. put_byte(val)
  445.     int             val;
  446. {
  447.     put_header(bytegen, (SIZE)AL_CHAR);
  448.     oprintf("%d", val & 0x00ff);
  449.     outcol += 4;
  450. }
  451.  
  452. PRIVATE void
  453. put_char(val)
  454.     int             val;
  455. {
  456.     put_byte(val);
  457. }
  458.  
  459. PRIVATE void
  460. put_word(val)
  461.     int             val;
  462. {
  463.     put_header(wordgen, (SIZE)AL_SHORT);
  464.     oprintf("%d", val & 0xffff);
  465.     outcol += 6;
  466. }
  467.  
  468. #ifndef FLOAT_BOOTSTRAP
  469. #ifdef FLOAT_IEEE
  470. PRIVATE void
  471. put_float(val)
  472.     double val;
  473. {
  474.     unsigned long ul;
  475.     ieee_single(val, &ul);
  476.     put_long((long) ul);
  477. }
  478.  
  479. PRIVATE void
  480. put_double(val)
  481.     double val;
  482. {
  483.     unsigned long ul[2];
  484.     ieee_double(val, ul);
  485.     put_long ((long) ul[0]);
  486.     put_long ((long) ul[1]);
  487. }
  488. PRIVATE void
  489. put_longdouble(val)
  490.     double val;
  491. {
  492.     unsigned long ul[2];
  493.     ieee_double(val, ul);
  494.     put_long ((long) ul[0]);
  495.     put_long ((long) ul[1]);
  496. }
  497. #endif /* FLOAT_IEEE */
  498. #ifdef FLOAT_MFFP
  499. PRIVATE void
  500. put_float(val)
  501.     double          val;
  502. {
  503.     put_long((long) genffp(val));
  504. }
  505.  
  506. PRIVATE void
  507. put_double(val)
  508.     double val;
  509. {
  510.     put_long((long) genffp(val));
  511. }
  512.  
  513. PRIVATE void
  514. put_longdouble(val)
  515.     double val;
  516. {
  517.     put_long((long) genffp(val));
  518. }
  519. #endif /* FLOAT_MFFP */
  520. #endif /* FLOAT_BOOTSTRAP */
  521.  
  522. PRIVATE void
  523. put_long(val)
  524.     long            val;
  525. {
  526.     put_header (longgen, (SIZE)AL_LONG);
  527.     oprintf("$%lx", val);
  528.     outcol += 10;
  529. }
  530.  
  531. #ifndef RELOC_BUG
  532. PRIVATE void
  533. put_short(node)
  534.     EXPR   *node;
  535. {
  536.     put_header (wordgen, (SIZE)AL_SHORT);
  537.     putconst(node);
  538.     outcol += 10;
  539. }
  540. #endif /* RELOC_BUG */
  541.  
  542. PRIVATE void
  543. put_pointer(node)
  544.     EXPR   *node;
  545. {
  546.     put_header (longgen, (SIZE)AL_POINTER);
  547.     putconst(node);
  548.     outcol += 10;
  549. }
  550.  
  551. PRIVATE void
  552. put_storage(sp, al)
  553.     SYM        *sp;
  554.     SIZE     al;
  555. {
  556.     bseg();
  557.     put_align(al);
  558. #if 0
  559.     if (sp->storage_class == sc_static) {
  560.     put_label (sp->value.l);
  561.     oprintf("\tds.b\t");
  562.     } else
  563.     oprintf("\tcomm\t%s,", outlate(sp->name));
  564.     oprintf("%ld\n", sp->tp->size);
  565. #else 
  566.     if (sp->storage_class == sc_static) {
  567.     put_label (sp->value.l);
  568.     } else
  569.     put_string (sp->name);
  570.     oprintf("\tds.b\t%ld\n", sp->tp->size);
  571. #endif
  572. }
  573.  
  574.  
  575. PRIVATE void
  576. dumplits()
  577. /*
  578.  * dump the string literal pool.
  579.  * if we are producing single copies of strings (which should therefore
  580.  * be read only we put them in the text segement - else in the data segment.
  581.  */
  582. {
  583.     char           *cp;
  584.     int             len;
  585.     if (trad_option || IandD_option)
  586.     dseg();
  587.     else
  588.     cseg();
  589.     for ( ; strtab != 0; strtab = strtab->next) {
  590.     nl();
  591.     put_label(strtab->label);
  592.     cp = strtab->str;
  593.     for (len = strtab->len; len--; )
  594.         put_char(*cp++);
  595.     put_byte(0);
  596.     }
  597.     nl();
  598. }
  599.  
  600. /*ARGSUSED*/
  601. PRIVATE void
  602. put_external(s)
  603.     char           *s;
  604. /* put the definition of an external name in the ouput file */
  605. {
  606.     s = s;    /* keep the compiler happy */
  607. }
  608.  
  609. PRIVATE void
  610. put_global(s)
  611.     char           *s;
  612. /* put the definition of a global name in the output file */
  613. {
  614.     nl();
  615.     oprintf("\tglobl\t%s\n", outlate(s));
  616. }
  617.  
  618. PRIVATE void
  619. put_align(al)
  620.     SIZE             al;
  621. /* align the following data */
  622. {
  623.     nl();
  624.     if (al > align_type) {
  625.     switch (al) {
  626.       case 2:
  627.       case 4:
  628.         oprintf("\teven\n");
  629.         break;
  630.     }
  631.     }
  632.     align_type = al;
  633. }
  634.  
  635. PRIVATE void
  636. nl()
  637. {
  638.     static BOOL    init_done = 0;
  639.     if (init_done == 0) {
  640. #ifdef VERBOSE
  641.     time_t time_of_day;
  642.     VOIDCAST time (&time_of_day);
  643. #endif /* VERBOSE */
  644.     init_done++;
  645.     oprintf(comment" Generated by %s v%s, %s (%s) from \"%s\"\n",
  646.         PROGNAME, VERSION, LAST_CHANGE_DATE, __DATE__, act_file);
  647. #ifdef VERBOSE
  648.     oprintf(comment" Compilation date/time: %s\n", ctime(&time_of_day));
  649. #endif /* VERBOSE */
  650.     } else if (outcol > 0) {
  651.     oprintf("\n");
  652.     gentype = nogen;
  653.     outcol = 0;
  654.     }
  655. }
  656.  
  657. static void
  658. seg(segtype, segname)
  659.     enum e_sg     segtype;
  660.     char    *segname;
  661. {
  662.     nl();
  663.     if (curseg != segtype) {
  664.     oprintf("\t%s\n", segname);
  665.     curseg = segtype;
  666.     align_type = 0;
  667.     }
  668. }
  669.  
  670. PRIVATE void
  671. cseg()
  672. {
  673.     seg(codeseg,"text");
  674. }
  675.  
  676. PRIVATE void
  677. dseg()
  678. {
  679.     seg(dataseg,"data");
  680. }
  681.  
  682. static void
  683. bseg()
  684. {
  685.     seg(bssseg,"bss");
  686. }
  687.  
  688. #ifdef MULTIPLE_ASSEMBLERS
  689. struct funcs jas68k_funcs = {
  690.     put_code,
  691.     put_string,
  692.     put_label,
  693.     put_byte,
  694.     put_char,
  695.     put_word,
  696.     put_long,
  697.     put_pointer,
  698. #ifndef RELOC_BUG
  699.     put_short,
  700. #endif /* RELOC_BUG */
  701.     put_storage,
  702.     dumplits,
  703.     put_external,
  704.     put_global,
  705.     put_align,
  706.     nl,
  707.     cseg,
  708.     dseg,
  709. #ifdef FLOAT_SUPPORT
  710.     put_float,
  711.     put_double,
  712.     put_longdouble
  713. #endif /* FLOAT_SUPPORT */
  714.     };
  715. #endif /* MULTIPLE_ASSEMBLERS */
  716. #endif /* TARGET_JAS */
  717. #endif /* MC680X0 */
  718.